package com.su.dolphin.core.notification;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import android.util.SparseArray;

public class DpMessageCenter
{
    private SparseArray<List<WeakReference<INotify>>> mNotificationMap = new SparseArray<List<WeakReference<INotify>>>();
    
    private static DpMessageCenter sInstance = null;
    
    public static DpMessageCenter i() {
        if (sInstance == null) {
            sInstance = new DpMessageCenter();
        }
        return sInstance;
    }
    
    /**
     * 在退出的时候清空通知map
     */
    public void cleanUpOnExit() {
        for (int i = 0; i < mNotificationMap.size(); i++) {
            List<WeakReference<INotify>> lists = mNotificationMap.get(i);
            if (lists != null) {
                lists.clear();
            }
        }
        mNotificationMap.clear();
    }
    
    /**
     * 注册MC消息 , 每个<b>类</b>只能注册一次, (以类名来区分, 而不是实例), 适用于Activity等
     * 
     * @param notify
     * @param mcmessageid
     */
    public void register(INotify notify, int mcmessageid) {
        register(notify, mcmessageid, true);
    }
    
    /**
     * 注册MC消息 , 同一个类不同实例都可以收到消息
     * 
     * @param notify
     * @param mcmessageid
     */
    public void registerAllInstance(INotify notify, int mcmessageid) {
        register(notify, mcmessageid, false);
    }
    
    /**
     * 注册MC消息.
     * 
     * @param notify
     * @param mcmessageid
     *            消息ID 在MCManager中
     * @param removeOtherInstance
     *            是否移除类名相同的其他实例, 如果是Activity很可能要移除
     */
    public void register(INotify notify, int mcmessageid, boolean removeOtherInstance) {
        List<WeakReference<INotify>> messages = mNotificationMap.get(mcmessageid);
        if (messages == null) {
            messages = new ArrayList<WeakReference<INotify>>();
            mNotificationMap.put(mcmessageid, messages);
        }
        
        for (Iterator<WeakReference<INotify>> iterator = messages.iterator(); iterator.hasNext();) {
            WeakReference<INotify> wNotify = iterator.next();
            if (wNotify != null) {
                INotify notifyInList = wNotify.get();
                if (notifyInList == null) {
                    iterator.remove();
                    continue;
                }
                if (removeOtherInstance) {
                    if (notify.getClass().getSimpleName().equals(notifyInList.getClass().getSimpleName())) {
                        iterator.remove();
                    }
                }
                
            }
        }
        messages.add(new WeakReference<INotify>(notify));
    }
    
    /**
     * 反注册 ,以类名为key 取消Activity的监听
     * 
     * @param notify
     * @param mcmessageid
     */
    public void unregister(INotify notify, int mcmessageid) {
        List<WeakReference<INotify>> messages = mNotificationMap.get(mcmessageid);
        if (messages != null) {
            for (Iterator<WeakReference<INotify>> iterator = messages.iterator(); iterator.hasNext();) {
                WeakReference<INotify> wNotify = iterator.next();
                if (wNotify != null) {
                    INotify notify2 = wNotify.get();
                    if (notify2 == null) {
                        iterator.remove();
                        continue;
                    }
                    //一个类, 只能注册一次!
                    if (notify2.getClass().getSimpleName().equals(notify.getClass().getSimpleName())) {
                        iterator.remove();
                    }
                }
            }
        }
    }
    
    public void notify(int mcmessageId) {
        notify(new MCMessage(mcmessageId));
    }
    
    /**
     * 发送MCMessage
     * 
     * @param mcmessage
     */
    public void notify(MCMessage mcmessage) {
        List<WeakReference<INotify>> messages = mNotificationMap.get(mcmessage.notificationID);
        if (messages != null) {
            for (Iterator<WeakReference<INotify>> iterator = messages.iterator(); iterator.hasNext();) {
                WeakReference<INotify> wNotify = iterator.next();
                if (wNotify != null) {
                    INotify notify = wNotify.get();
                    if (notify == null) {
                        iterator.remove();
                    }
                    else {
                        try {
                            notify.onNotifyInner(mcmessage);
                        }
                        catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                
            }
        }
        
    }
    
    public interface INotify
    {
        public void onNotifyInner(MCMessage mcmessage);
    }
    
    public static class MCMessage
    {
        public int notificationID;
        public Object extObj;
        
        public MCMessage(int id, Object extObj) {
            this.notificationID = id;
            this.extObj = extObj;
        }
        
        public MCMessage(int id) {
            this(id, null);
        }
    }
}
